home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / ddx-mips.zip / MIPSINIT.C < prev    next >
C/C++ Source or Header  |  1992-08-17  |  15KB  |  698 lines

  1. /*
  2.  * $XConsortium: mipsInit.c,v 1.4 91/07/12 20:48:54 keith Exp $
  3.  *
  4.  * Copyright 1991 MIPS Computer Systems, Inc.
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of MIPS not be used in advertising or
  11.  * publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  MIPS makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  *
  16.  * MIPS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  17.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL MIPS
  18.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
  21.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  */
  23. #ident    "$Header: mipsInit.c,v 1.19 92/08/11 16:38:00 dd Exp $"
  24.  
  25. #include <sys/types.h>
  26. #include <sysv/sys/lock.h>
  27.  
  28. #include "X.h"
  29. #include "Xproto.h"
  30. #include "keysym.h"
  31. #include "input.h"
  32. #include "cursor.h"
  33. #include "colormapst.h"
  34. #include "scrnintstr.h"
  35. #include "servermd.h"
  36. #include "mipointer.h"
  37.  
  38. #include "mips.h"
  39. #include "mipsFb.h"
  40. #include "mipsIo.h"
  41. #include "mipsKbd.h"
  42. #include "mipsMouse.h"
  43.  
  44. int mipsSysType;
  45.  
  46. extern int    mipsMouseProc(), mipsKeybdProc();
  47.  
  48. extern int      defaultColorVisualClass;
  49. extern int monitorResolution;
  50. int DDXabort;    /* call abort() on fatal error if set */
  51. int        DDXnoreset = 0;
  52. int        DDXxled1 = 0;
  53. int        DDXxled2 = 0;
  54. int        DDXxled3 = 0;
  55. static int mipsScreenTypeWanted;
  56. int mipsMonitorSize;
  57. static int mipsNoFBHW;
  58. static int mipsNoFBCache;
  59. static char *blackPixelName = "black";
  60. static char *whitePixelName = "white";
  61.  
  62. #if NETWORK_KEYBD
  63. extern char    *netKeybdAddr;
  64. #endif /* NETWORK_KEYBD */
  65. #if EMULATE_COLOR || EMULATE_MONO
  66. int        DDXemulate = 0;
  67. #endif /* EMULATE_COLOR || EMULATE_MONO */
  68. #if PIXIE
  69. int        pixie = 0;
  70. #endif /* PIXIE */
  71.  
  72. /* Globals for io */
  73.  
  74. DevicePtr    pPointer;
  75. DevicePtr    pKeyboard;
  76. volatile extern int    mipsIOReady;
  77.  
  78. MipsScreenRec mipsScreen[MAXSCREENS];
  79.  
  80. extern Bool mipsMap4000();
  81. #ifndef _MIPSEL
  82. extern Bool mipsMap2030();
  83. extern Bool mipsMap3230c();
  84. extern Bool mipsMap3230m();
  85. #endif
  86.  
  87. static Bool (*mipsMapProc[][2])() = {
  88.     IFMIPSEL(0, mipsMap2030),
  89.     0,
  90.     IFMIPSEL(0, mipsMap3230c),
  91.     IFMIPSEL(0, mipsMap3230m),
  92.     mipsMap4000,
  93.     0,
  94. };
  95.  
  96. /*
  97.  * We don't have real frame buffer devices, so as a hack
  98.  * we always use unit 0 for the color screen and unit 1 for
  99.  * the mono screen
  100.  */
  101. #define COLOR_UNIT    0
  102. #define MONO_UNIT    1
  103.  
  104. /* supported pixmap formats */
  105. static PixmapFormatRec formats[] = {
  106.     {8, 8, BITMAP_SCANLINE_PAD},
  107.     {1, 1, BITMAP_SCANLINE_PAD},
  108. };
  109. #define NUMFORMATS    sizeof(formats)/sizeof(formats[0])
  110.  
  111. extern void mipsInstallColormap();
  112. extern void mipsUninstallColormap();
  113. extern int mipsListInstalledColormaps();
  114. extern void mipsStoreColors();
  115. Bool mipsScreenInit();
  116. static Bool mipsSaveScreen();
  117. static Bool mipsCloseScreen();
  118.  
  119. InitOutput(screenInfo, argc, argv)
  120.     ScreenInfo *screenInfo;
  121.     int argc;
  122.     char **argv;
  123. {
  124.     int i;
  125.  
  126.     if ((mipsSysType = cpubd()) < 0)
  127.         FatalError("invalid or unsupported system type");
  128.  
  129.     screenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
  130.     screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
  131.     screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
  132.     screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
  133.  
  134.     screenInfo->numPixmapFormats = 1;
  135.     screenInfo->formats[0] = formats[0];
  136.  
  137.     if (!mipsFindFb(0)) {
  138.         if (mipsScreenTypeWanted)
  139.             MipsScreenNumToPriv(0)->type = mipsScreenTypeWanted;
  140.         else {
  141.             MipsScreenNumToPriv(COLOR_UNIT)->type =
  142.                 MIPS_SCRTYPE_COLOR;
  143.             MipsScreenNumToPriv(MONO_UNIT)->type =
  144.                 MIPS_SCRTYPE_MONO;
  145.         }
  146.         if (!mipsFindFb(1))
  147.             return;
  148.     }
  149.  
  150.     for (i = 0; i < MAXSCREENS; i++) {
  151.         MipsScreenPtr pm = MipsScreenNumToPriv(i);
  152.  
  153.         if (pm->type == MIPS_SCRTYPE_DISABLED)
  154.             continue;
  155.  
  156.         if (monitorResolution)
  157.             pm->dpi = monitorResolution;
  158.  
  159.         if (pm->bitsPerPixel > 1) {
  160.             screenInfo->numPixmapFormats = 2;
  161.             screenInfo->formats[1] = formats[1];
  162.         }
  163.  
  164.         (void) AddScreen(mipsScreenInit, argc, argv);
  165.     }
  166. }
  167.  
  168. static
  169. mipsFindFb(how)
  170.     int how;
  171. {
  172.     int i;
  173.     int foundfb;
  174.  
  175.     for (i = 0; i < MAXSCREENS; i++) {
  176.         MipsScreenPtr pm = MipsScreenNumToPriv(i);
  177.  
  178.         pm->unit = i;
  179.  
  180.         if (mipsNoFBCache)
  181.             pm->option |= MIPS_SCR_NOCACHE;
  182.  
  183.         if (mipsNoFBHW)
  184.             pm->option |= MIPS_SCR_NOHW;
  185.  
  186.         if (how == 0) {
  187. #if MIPS_RISCOS_VERSION >= 5
  188.             char fbname[32];
  189.  
  190.             sprintf(fbname, "/dev/fb%d", i);
  191.  
  192.             if ((pm->fd = open(fbname, 2)) < 0)
  193.                 continue;
  194.  
  195.             if (!mipsMapFb(pm)) {
  196.                 (void) close(pm->fd);
  197.                 bzero((char *) pm, sizeof *pm);
  198.                 continue;
  199.             }
  200.  
  201.             pm->type = pm->depth > 1 ?
  202.                 MIPS_SCRTYPE_COLOR : MIPS_SCRTYPE_MONO;
  203. #else /* MIPS_RISCOS_VERSION >= 5 */
  204.             continue;
  205. #endif /* MIPS_RISCOS_VERSION >= 5 */
  206.         }
  207.         else {
  208.             Bool(*fun) ();
  209.  
  210.             if (pm->type == MIPS_SCRTYPE_DISABLED)
  211.                 continue;
  212.  
  213.             if (!(fun = mipsMapProc[mipsSysType][pm->type - 1]) ||
  214.                 !(*fun)(pm)) {
  215.                 /*
  216.                  * If probe fails on color screen, make
  217.                  * the mono screen screen 0 instead of
  218.                  * screen 1.  Urk.
  219.                  */
  220.                 if (i == COLOR_UNIT) {
  221.                     pm->type = pm[MONO_UNIT].type;
  222.                     pm[MONO_UNIT].type = MIPS_SCRTYPE_DISABLED;
  223.                     i--;
  224.                 }
  225.                 else
  226.                     pm->type = MIPS_SCRTYPE_DISABLED;
  227.                 continue;
  228.             }
  229.         }
  230.         foundfb = 1;
  231.     }
  232.     return foundfb;
  233. }
  234.  
  235. /*ARGSUSED*/
  236. Bool
  237. mipsScreenInit(index, pScreen, argc, argv)
  238.     int index;
  239.     ScreenPtr pScreen;
  240.     int argc;
  241.     char *argv[];
  242. {
  243.     MipsScreenPtr pm = MipsScreenNumToPriv(index);
  244.     int fbtype = pm->type;
  245.     Bool (*fun)();
  246.     extern Bool cfbScreenInit();
  247.     extern Bool mfbScreenInit();
  248.     extern Bool mipsCreateDefColormap();
  249.     
  250.     fun = fbtype == MIPS_SCRTYPE_COLOR ?
  251.         cfbScreenInit : mfbScreenInit;
  252.     if (!(*fun)(pScreen, (pointer) pm->fbnorm,
  253.         pm->scr_width, pm->scr_height,
  254.         pm->dpi, pm->dpi,
  255.         pm->fb_width))
  256.         return FALSE;
  257.  
  258.     if (fbtype == MIPS_SCRTYPE_COLOR) {
  259. #ifndef STATIC_COLOR
  260.         pScreen->InstallColormap = mipsInstallColormap;
  261.         pScreen->UninstallColormap = mipsUninstallColormap;
  262.         pScreen->ListInstalledColormaps = mipsListInstalledColormaps;
  263.         pScreen->StoreColors = mipsStoreColors;
  264. #endif /* STATIC_COLOR */
  265. #if MIPS_4BIT
  266.         if (pm->depth == 4)
  267.             mipsFixScreen4(pScreen);
  268. #endif /* MIPS_4BIT */
  269.     }
  270.     else {
  271.         pScreen->whitePixel =   1;
  272.         pScreen->blackPixel =   0;
  273.     }
  274.  
  275.     pm->CloseScreen = pScreen->CloseScreen;
  276.     pScreen->CloseScreen = mipsCloseScreen;
  277.  
  278.     pScreen->SaveScreen = mipsSaveScreen;
  279.     (void) mipsSaveScreen(pScreen, SCREEN_SAVER_FORCER);
  280.  
  281. #ifdef X11R4
  282.     {
  283.         extern miPointerCursorFuncRec mipsPointerCursorFuncs;
  284.  
  285.         if (!miDCInitialize(pScreen, &mipsPointerCursorFuncs))
  286.             return FALSE;
  287.     }
  288. #else /* X11R4 */
  289.     if (!mipsCursorInit(pm, pScreen))
  290.         return FALSE;
  291. #endif /* X11R4 */
  292.  
  293.     return mipsCreateDefColormap(index, pScreen,
  294.         whitePixelName, blackPixelName);
  295. }
  296.  
  297. static Bool
  298. mipsSaveScreen(pScreen, on)
  299.     ScreenPtr pScreen;
  300.     Bool on;
  301. {
  302.     MipsScreenPtr pm = MipsScreenToPriv(pScreen);
  303.  
  304.     if (on != SCREEN_SAVER_ON)
  305.         lastEventTime = GetTimeInMillis();
  306.  
  307.     if (pm->Blank)
  308.         (*pm->Blank)(pm, on);
  309.  
  310.     return TRUE;
  311. }
  312.  
  313. static Bool
  314. mipsCloseScreen(i, pScreen)
  315.     int i;
  316.     ScreenPtr pScreen;
  317. {
  318.     MipsScreenPtr pm = MipsScreenToPriv(pScreen);
  319.     Bool ret;
  320.  
  321.     SIGIGNORE;
  322.  
  323.     pScreen->CloseScreen = pm->CloseScreen;
  324.     ret = (*pScreen->CloseScreen) (i, pScreen);
  325.     (void) (*pScreen->SaveScreen) (pScreen, SCREEN_SAVER_OFF);
  326.     if (pm->Close)
  327.         (*pm->Close)(pm);
  328.     return ret;
  329. }
  330.  
  331. /* Open input from the mouse and keyboard */
  332.  
  333. /* ARGSUSED */
  334. void
  335. InitInput(argc, argv)
  336. int argc;
  337. char *argv[];
  338. {
  339.     extern int    sigIOfunc();
  340.     static int    zero = 0;
  341.  
  342.     initKeybd();
  343.  
  344.     pPointer = AddInputDevice(mipsMouseProc, TRUE);
  345.     pKeyboard = AddInputDevice(mipsKeybdProc, TRUE);
  346.  
  347.     RegisterPointerDevice(pPointer);
  348.     RegisterKeyboardDevice(pKeyboard);
  349.     miRegisterPointerDevice(screenInfo.screens[0], pPointer);
  350.  
  351. #ifdef X11R4
  352.     SetInputCheck(&zero, &mipsIOReady);
  353. #else /* X11R4 */
  354.     if (!mieqInit(pKeyboard, pPointer))
  355.     return;
  356. #endif /* X11R4 */
  357.  
  358.     SIGCATCH(sigIOfunc);
  359. }
  360.  
  361. /* DDX - specific abort routine.  Called by AbortServer(). */
  362.  
  363. void
  364. AbortDDX()
  365. {
  366.     MipsScreenPtr pm;
  367.  
  368.     for (pm = MipsScreenNumToPriv(0);
  369.         pm < MipsScreenNumToPriv(MAXSCREENS); pm++)
  370.         if (pm->Close)
  371.             (*pm->Close)(pm);
  372. }
  373.  
  374. /* Called by GiveUp(). */
  375.  
  376. void
  377. ddxGiveUp()
  378. {
  379.     AbortDDX();
  380. }
  381.  
  382. #define    BAD_ARG    (-66)    /* convenient invalid argument */
  383.  
  384. /* Process command line arguments specific to mips Xserver */
  385. int
  386. ddxProcessArgument(argc, argv, i)
  387.     int argc;
  388.     char *argv[];
  389.     int i;
  390. {
  391.     char *arg;
  392.     int v;
  393.     static void BadUse();
  394.  
  395.     argv += i;
  396.     argc -= i;
  397.     arg = argv[0];
  398.  
  399.     if (matcharg(arg, "-bp") == 0) {
  400.         if (argc < 2)
  401.             BadUse();
  402.         blackPixelName = argv[1];
  403.         return 2;
  404.     }
  405.     if (matcharg(arg, "-wp") == 0) {
  406.         if (argc < 2)
  407.             BadUse();
  408.         whitePixelName = argv[1];
  409.         return 2;
  410.     }
  411. #ifdef X11R4
  412.     if (matcharg(arg, "-mb") == 0) {
  413.         extern int motionBufferSize;
  414.  
  415.         if (argc < 2)
  416.             BadUse();
  417.         v = atoi(argv[1]);
  418.         if (v < 0)
  419.             v = 0;
  420.         if (v > 1024)
  421.             v = 1024;
  422.         motionBufferSize = v;
  423.         return 2;
  424.     }
  425. #endif /* X11R4 */
  426.     if (matcharg(arg, "-pl*ock") == 0) {
  427.         (void) plock(PROCLOCK);
  428.         return 1;
  429.     }
  430.     if (matcharg(arg, "-tl*ock") == 0) {
  431.         (void) plock(TXTLOCK);
  432.         return 1;
  433.     }
  434.     if (matcharg(arg, "-dl*ock") == 0) {
  435.         (void) plock(DATLOCK);
  436.         return 1;
  437.     }
  438.     if (matcharg(arg, "-ni*ce") == 0) {
  439.         if (argc < 2)
  440.             BadUse();
  441.         (void) nice(atoi(argv[1]));
  442.         return 2;
  443.     }
  444.     if (matcharg(arg, "-ab*ort") == 0) {
  445.         DDXabort = 1;
  446.         return 1;
  447.     }
  448.     if (matcharg(arg, "-nor*eset") == 0) {
  449.         DDXnoreset = 1;
  450.         return 1;
  451.     }
  452.     if (matcharg(arg, "-xled1") == 0) {
  453.         DDXxled1 = 1;
  454.         return 1;
  455.     }
  456.     if (matcharg(arg, "-xled2") == 0) {
  457.         DDXxled2 = 1;
  458.         return 1;
  459.     }
  460.     if (matcharg(arg, "-xled3") == 0) {
  461.         DDXxled3 = 1;
  462.         return 1;
  463.     }
  464.     if (matcharg(arg, "-vi*sual") == 0) {
  465.         if (argc < 2)
  466.             BadUse();
  467.  
  468.         if ((v = matchargs(argv[1], BAD_ARG,
  469.             "d*efault", -1,
  470.             "staticg*ray", StaticGray,
  471.             "g*rayscale", GrayScale,
  472.             "staticc*olor", StaticColor,
  473.             "p*seudocolor", PseudoColor,
  474.             (char *) 0)) == BAD_ARG)
  475.             BadUse();
  476.  
  477.         defaultColorVisualClass = v;
  478.         return 2;
  479.     }
  480.     if (matcharg(arg, "-en*able") == 0) {
  481.         if (argc < 2)
  482.             BadUse();
  483.         if ((v = matchargs(argv[1], BAD_ARG,
  484.             "c*olor", MIPS_SCRTYPE_COLOR,
  485.             "m*onochrome", MIPS_SCRTYPE_MONO,
  486.             (char *) 0)) == BAD_ARG)
  487.             BadUse();
  488.         mipsScreenTypeWanted = v;
  489.         return 2;
  490.     }
  491.     if (matcharg(arg, "-mo*nochrome") == 0) {
  492.         mipsScreenTypeWanted = MIPS_SCRTYPE_MONO;
  493.         return 1;
  494.     }
  495.     if (matcharg(arg, "-1*9inch") == 0) {
  496.         mipsMonitorSize = 19;
  497.         return 1;
  498.     }
  499.     if (matcharg(arg, "-noca*che") == 0) {
  500.         mipsNoFBCache = 1;
  501.         return 1;
  502.     }
  503.     if (matcharg(arg, "-nohw") == 0) {
  504.         mipsNoFBHW = 1;
  505.         return 1;
  506.     }
  507.     if (matcharg(arg, "-k*eyboard") == 0) {
  508.         if (argc < 2)
  509.             BadUse();
  510.         if ((v = matchargs(argv[1], BAD_ARG,
  511.             "de*fault", DEFAULT_KEYBOARD,
  512. #ifdef AT_KEYBOARD
  513.             "at", AT_KEYBOARD,
  514. #endif                /* AT_KEYBOARD */
  515. #ifdef XT_KEYBOARD
  516.             "xt", XT_KEYBOARD,
  517. #endif                /* XT_KEYBOARD */
  518. #ifdef UNIX1_KEYBOARD
  519.             "unix", UNIX1_KEYBOARD,
  520. #endif                /* UNIX1_KEYBOARD */
  521.             (char *) 0)) == BAD_ARG)
  522.             BadUse();
  523.         keybdPriv.type = v;
  524.  
  525.         if (argc < 3 || argv[2][0] == '-')
  526.             return 2;
  527.             
  528.         keybdPriv.unit = atoi(argv[2]);
  529.         return 3;
  530.     }
  531.     if (matcharg(arg, "-po*inter") == 0) {
  532.         if (argc < 2)
  533.             BadUse();
  534.         if ((v = matchargs(argv[1], BAD_ARG,
  535.             "de*fault", MIPS_MOUSE_DEFAULT,
  536.             "m*", MIPS_MOUSE_MOUSEMAN,
  537.             (char *) 0)) == BAD_ARG)
  538.             BadUse();
  539.         mousePriv.type = v;
  540.  
  541.         if (argc < 3 || argv[2][0] == '-')
  542.             return 2;
  543.             
  544.         mousePriv.unit = atoi(argv[2]);
  545.  
  546.         if (argc < 4 || argv[3][0] == '-')
  547.             return 3;
  548.  
  549.         mousePriv.baud = atoi(argv[3]);
  550.  
  551.         if (argc < 5 || argv[4][0] == '-')
  552.             return 4;
  553.  
  554.         mousePriv.rate = atoi(argv[5]);
  555.  
  556.         return 5;
  557.     }
  558. #if NETWORK_KEYBD
  559.     if (matcharg(arg, "-ne*tkeybd") == 0) {
  560.         if (argc < 2)
  561.             BadUse();
  562.         netKeybdAddr = argv[1];
  563.         return 2;
  564.     }
  565. #endif                /* NETWORK_KEYBD */
  566. #if EMULATE_COLOR || EMULATE_MONO
  567.     if (matcharg(arg, "-em*ulate") == 0) {
  568.         DDXemulate = 1;
  569.         return 1;
  570.     }
  571. #endif                /* EMULATE_COLOR || EMULATE_MONO */
  572. #if PIXIE
  573.     if (matcharg(arg, "-pi*xie") == 0) {
  574.         pixie = 1;
  575.         return 1;
  576.     }
  577. #endif                /* PIXIE */
  578.     return 0;
  579. }
  580.  
  581. /* print use message and quit */
  582. static void
  583. BadUse()
  584. {
  585.     extern void UseMsg();
  586.  
  587.     UseMsg();
  588.     exit(1);
  589. }
  590.  
  591. /* Print use message for command line arguments specific to mips Xserver */
  592.  
  593. static char *usetext[] = {
  594. "-bp color        set default black-pixel color\n\
  595. -wp color        set default white-pixel color\n\
  596. -plock            process lock the server\n\
  597. -tlock            text lock the server\n\
  598. -dlock            data lock the server\n\
  599. -nice incr        change the scheduling priority of the server\n\
  600. -noreset        do not reset server on last client close\n\
  601. -xled1            use LED for xled1 instead of Scroll Lock\n\
  602. -xled2            use LED for xled2 instead of Caps Lock\n\
  603. -xled3            use LED for xled3 instead of Num Lock\n\
  604. -visual PseudoColor|StaticColor|GrayScale|StaticGray\n\
  605.             use grayscale/color visual on the color screen\n\
  606. -enable color|mono    enable the color and/or mono screens\n\
  607. -19inch            set color screen dpi for 19\" monitor\n\
  608. -keyboard Default|AT|XT|UNIX [unit#]\n\
  609.             select type of keyboard to use\n\
  610. -pointer Default|Mouseman [unit#] [baud] [sample_rate]\n\
  611.             select type of pointer device to use",
  612. #ifdef X11R4
  613. "-mb size        size of motion buffer (0-1024, default 100)\n",
  614. #endif /* X11R4 */
  615. #if NETWORK_KEYBD
  616. "-netkeybd net-addr    connect to keyboard at network address",
  617. #endif /* NETWORK_KEYBD */
  618. #if EMULATE_COLOR || EMULATE_MONO
  619. "-emulate        emulate color or mono screens",
  620. #endif /* EMULATE_COLOR || EMULATE_MONO */
  621. #if PIXIE
  622. "-pixie            enable use of pixie analysis",
  623. #endif /* PIXIE */
  624.     0
  625. };
  626.  
  627. void
  628. ddxUseMsg()
  629. {
  630.     char **p;
  631.  
  632.     for (p = usetext; *p; p++)
  633.         ErrorF("%s\n", *p);
  634. }
  635.  
  636. /*
  637.  * match argument against list of keywords
  638.  * "*" in keyword allows prefix match
  639.  */
  640.  
  641. #include <varargs.h>
  642. #include <ctype.h>
  643.  
  644. /* arg, bad val, key, ret val, key, ret val, 0 */
  645. /*VARARGS*/
  646. static int
  647. matchargs(va_alist)
  648. va_dcl
  649. {
  650.     va_list ap;
  651.     char *arg, *key;
  652.     int ret;
  653.  
  654.     va_start(ap);
  655.     arg = va_arg(ap, char *);
  656.     ret = va_arg(ap, int);
  657.  
  658.     while (key = va_arg(ap, char *)) {
  659.         int val = va_arg(ap, int);
  660.         char *ac = arg;
  661.         int star = 0;
  662.  
  663.         for (;;) {
  664.             char k = *key++, a = *ac++;
  665.  
  666.             if (isascii(a) && isupper(a))
  667.                 a = tolower(a);
  668.  
  669.             /* XXX once we've seen the star we have
  670.             to remember abbrevs are OK */
  671.             if (k == '*') {
  672.                 star = 1;
  673.                 if (a == 0) {
  674.                     ret = val;
  675.                     break;
  676.                 }
  677.                 ac--;
  678.                 continue;
  679.             }
  680.             if (a != k && !star)
  681.                 break;
  682.             if (a == 0) {
  683.                 ret = val;
  684.                 break;
  685.             }
  686.         }
  687.     }
  688.     va_end(ap);
  689.     return ret;
  690. }
  691.  
  692. static int
  693. matcharg(arg, key)
  694.     char *arg, *key;
  695. {
  696.     return matchargs(arg, -1, key, 0, (char *) 0);
  697. }
  698.